//
//  KEqualizeChannel.m
//  Kia
//
//  Created by Andrey on 06/05/2009.
//  Copyright 2009 Karma Software. All rights reserved.
//

#import "KEqualizeChannel.h"
#import "KPixel.h"
#import "KImage.h"
#import "KCumulativeHistogram.h"
/*
CGFloat GetEqualizedColorComponent(NSUInteger histogramLowEnd, NSUInteger histogramHighEnd, 
								   NSUInteger histogramIntervalCount, 
								   CGFloat component)
{
	CGFloat histogramSpan = 
	histogramHighEnd - histogramLowEnd;
	
	NSUInteger interval = (NSUInteger)(histogramIntervalCount * component);
	if (interval >= histogramIntervalCount)
		interval = histogramIntervalCount - 1;
	
	return (componentHistogramData[interval] - histogramLowEnd) / histogramSpan;
}
*/
NSUInteger GetIntervalForValue(CGFloat value, NSUInteger intervalCount)
{
	NSUInteger interval = (NSUInteger)(intervalCount * value);
	
	if (interval >= intervalCount)
		interval = interval - 1;
	
	return interval;
}

@implementation KEqualizeChannel

- (void) computeHistogramSpan: (KImage*)image
{
	enum KImageChannel channelToEqualize = GetParameterUIntValue(@"ChannelToEqualize");
	KCumulativeHistogram* cumulativeHistogram = image.cumulativeHistogram;
	
	histogramIntervalCount = cumulativeHistogram.intervalCount;
	affectedChannelHistogramData = 
	cumulativeHistogram.channelHistograms[channelToEqualize].data;
	histogramHighEnd = affectedChannelHistogramData[histogramIntervalCount - 1];
	histogramLowEnd = affectedChannelHistogramData[0];
}

- (KPixel*) processPixel: (KPixel*)pixel ofImage: (KImage*)image atX: (NSUInteger)x y: (NSUInteger)y
{
	if (image != currentImage)
	{
		currentImage = image;
		[self computeHistogramSpan:image];
	}
	enum KImageChannel channelToEqualize = GetParameterUIntValue(@"ChannelToEqualize");
	
	CGFloat previousComponentValue = 
	[pixel redundantColorVector].data[channelToEqualize];
	NSUInteger intervalForValue = 
	GetIntervalForValue(previousComponentValue, histogramIntervalCount);
	
	CGFloat equalizedComponent = 
	(CGFloat)(affectedChannelHistogramData[intervalForValue] - histogramLowEnd) / 
	(histogramHighEnd - histogramLowEnd);
	
	[pixel setValue:equalizedComponent forChannel:channelToEqualize];
	
	return pixel;
}

- (KImage*) processImage: (KImage*)image inPlace: (Boolean)inPlace
{
	[self computeHistogramSpan:image];
	enum KImageChannel channelToEqualize = GetParameterUIntValue(@"ChannelToEqualize");
	
	ForEachImagePixel(image)
	{
		KPixel* currentPixel = [image pixelAtX:x y:y];
		
		CGFloat previousComponentValue = 
		[currentPixel redundantColorVector].data[channelToEqualize];
		NSUInteger intervalForValue = 
		GetIntervalForValue(previousComponentValue, histogramIntervalCount);
		
		CGFloat equalizedComponent = 
		(CGFloat)(affectedChannelHistogramData[intervalForValue] - histogramLowEnd) / 
		(histogramHighEnd - histogramLowEnd);
		
		[currentPixel setValue:equalizedComponent forChannel:channelToEqualize]; 
	}
	
	[self reset];
	
	return image;
}

- (NSString*) name
{
	return @"Equalize Channel";
}

- (void) dealloc
{
	[super dealloc];
}

@end
